<template>
  <el-form label-width="100px" v-loading="loading">
    <el-form-item label="SPU名称">
      <el-input placeholder="请输入SPU名称" v-model="spuParams.spuName" />
    </el-form-item>

    <el-form-item label="SPU品牌">
      <el-select placeholder="请选择SPU品牌" v-model="spuParams.tmId">
        <el-option v-for="item in allTradeMark" :label="item.tmName" :value="item.id" :key="item.id" />
      </el-select>
    </el-form-item>

    <el-form-item label="SPU描述">
      <el-input placeholder="请输入SPU描述" type="textarea" v-model="spuParams.description" />
    </el-form-item>

    <el-form-item label="SPU图片">
      <el-upload
        v-model:file-list="imgList"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :before-upload="handleUpload"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>

      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%; height: 100%" />
      </el-dialog>
    </el-form-item>

    <el-form-item label="SPU销售属性">
      <el-select v-model="saleAttrIdAndAValueName" :placeholder="unSelectSaleAttr?.length ? `还未选择的${unSelectSaleAttr.length}个` : `无`">
        <el-option v-for="item in unSelectSaleAttr" :label="item.name" :value="`${item.id}:${item.name}`" :key="item.id" />
      </el-select>
      <el-button @click="addSaleAttr" :disabled="!saleAttrIdAndAValueName" style="margin-left: 10px" type="primary" size="default" icon="Plus">添加属性</el-button>

      <el-table border style="margin: 10px 0" :data="saleAttr">
        <el-table-column label="序号" type="index" align="center" width="80px" />
        <el-table-column label="销售属性名字" prop="saleAttrName" wdith="120px" />

        <el-table-column label="销售属性值">
          <template #="{ row, $index }">
            <el-tag v-for="(item, index) in row.spuSaleAttrValueList" :key="item.id" style="margin-left: 5px" closable @close="row.spuSaleAttrValueList.splice(index, 1)">
              {{ item.saleAttrValueName }}
            </el-tag>
            <el-input
              :ref="(vc: any) => (inputRefs[$index] = vc)"
              v-if="row.flag"
              v-model="row.saleAttrValue"
              placeholder="请输入属性值"
              size="small"
              @blur="handleBlur(row)"
              style="width: 100px; margin: 0 5px"
            />
            <el-button v-else style="margin-left: 5px" size="small" icon="Plus" type="success" @click="toEdit(row, $index)" />
          </template>
        </el-table-column>

        <el-table-column label="操作">
          <template #="{ $index }">
            <el-button type="danger" size="small" @click="saleAttr.splice($index, 1)" icon="Delete" title="删除"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>

    <el-form-item>
      <el-button :disabled="!saleAttr.length" type="primary" size="default" icon="Plus" @click="save">保存</el-button>
      <el-button type="primary" size="default" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
  import { ref, computed, nextTick } from 'vue'
  import type { UploadProps } from 'element-plus'
  import type { SpuData, AllTradeMark, SpuHasImg, SaleAttrResponseData, HasSaleAttrResponse, SaleAttr, SpuImg, HasSaleAttr, SaleAttrValue } from '@/api/product/spu/type'
  import { reqAllTradeMark, reqSpuImageList, reqAllSaleAttr, reqSpuHasSaleAttr, reqAddOrUpdateSpu } from '@/api/product/spu/index'
  import { getElMessage } from '@/utils/message'
  import { TradeMark } from '@/api/product/trademark/type'

  const $emit = defineEmits(['changeScene'])
  function cancel(isEidt: boolean = false) {
    $emit('changeScene', { flag: 0, isEidt: isEidt })
  }

  const inputRefs = ref<any>([])
  const spuParams = ref<SpuData>({
    category3Id: '',
    description: '',
    spuName: '',
    spuImageList: [],
    tmId: '',
    spuSaleAttrList: [],
  })

  const loading = ref<boolean>(false)
  const saleAttrIdAndAValueName = ref<string>('')
  async function initalHasSpuData(row: SpuData | number | string) {
    loading.value = true
    getAllTradeMark()
    getAllSaleAttr()
    if (typeof row === 'number' || typeof row === 'string') {
      Object.assign(spuParams.value, {
        category3Id: row,
        description: '',
        spuName: '',
        spuImageList: [],
        tmId: '',
        spuSaleAttrList: [],
        id: '',
      })
      imgList.value = []
      saleAttr.value = []
      saleAttrIdAndAValueName.value = ''
    } else {
      spuParams.value = JSON.parse(JSON.stringify(row))
      // 编辑
      getSquImageList(row.id as number)
      getSpuHasSaleAttr(row.id as number)
    }
    loading.value = false
  }

  const allTradeMark = ref<TradeMark[]>([])
  async function getAllTradeMark() {
    try {
      const res: AllTradeMark = await reqAllTradeMark()
      allTradeMark.value = res.data
      if (res.code !== 200) {
        getElMessage('获取销售属性列表失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    }
  }
  const imgList = ref<SpuImg[]>([])
  async function getSquImageList(id: number) {
    try {
      const res: SpuHasImg = await reqSpuImageList(id)
      imgList.value = res.data.map((item) => {
        return {
          name: item.imgName,
          url: item.imgUrl,
        }
      })
      if (res.code !== 200) {
        getElMessage('获取销售属性图片列表失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    }
  }
  const saleAttr = ref<SaleAttr[]>([])
  async function getSpuHasSaleAttr(id: number) {
    try {
      const res: SaleAttrResponseData = await reqSpuHasSaleAttr(id)
      saleAttr.value = res.data
      if (res.code !== 200) {
        getElMessage('获取销售属性失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    }
  }
  const allSaleAttr = ref<HasSaleAttr[]>()
  async function getAllSaleAttr() {
    try {
      const res: HasSaleAttrResponse = await reqAllSaleAttr()
      allSaleAttr.value = res.data
      if (res.code !== 200) {
        getElMessage('获取已有销售属性失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    }
  }

  const dialogVisible = ref<boolean>(false)
  const dialogImageUrl = ref<string>('')
  const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
    dialogImageUrl.value = uploadFile.url!
    dialogVisible.value = true
  }
  // 不需要这个方法， 因为使用的v-model双向绑定
  const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
    console.log(uploadFile, uploadFiles)
  }

  const handleUpload: UploadProps['beforeUpload'] = (rawFile) => {
    if (rawFile.type == 'image/jpeg' || rawFile.type == 'image/png' || rawFile.type == 'image/gif') {
      if (rawFile.size / 1024 / 1024 < 3) {
        return true
      } else {
        getElMessage('上传图片不能超过3kb', 'warning')
      }
    } else {
      getElMessage('上传图片后缀为jpeg，png，gif格式', 'warning')
    }
  }

  let unSelectSaleAttr = computed(() => {
    let unSelectArr = allSaleAttr.value?.filter((item) => {
      return saleAttr.value.every((item1) => {
        return item.name !== item1.saleAttrName
      })
    })
    return unSelectArr
  })

  function addSaleAttr() {
    const [baseSaleAttrId, saleAttrName] = saleAttrIdAndAValueName.value.split(':')
    saleAttr.value.push({
      baseSaleAttrId,
      saleAttrName,
      spuSaleAttrValueList: [],
    })

    saleAttrIdAndAValueName.value = ''
  }

  function toEdit(row: SaleAttr, index: number) {
    row.flag = true
    row.saleAttrValue = ''
    nextTick(() => {
      inputRefs.value[index].focus()
    })
  }

  function handleBlur(row: SaleAttr) {
    const { saleAttrValue, baseSaleAttrId } = row
    if (!saleAttrValue?.trim()) {
      return getElMessage('请输入属性值', 'warning')
    }

    // 判断是否属性值是否存在
    let repeat = row.spuSaleAttrValueList.find((o) => o.saleAttrValueName === saleAttrValue)
    if (repeat) {
      return getElMessage('该属性值已存在', 'warning')
    }

    let newSaleAttrValue: SaleAttrValue = {
      baseSaleAttrId,
      saleAttrValueName: saleAttrValue as string,
    }
    row.spuSaleAttrValueList.push(newSaleAttrValue)

    row.saleAttrValue = ''
    row.flag = false
  }

  async function save() {
    try {
      // 整理参数
      spuParams.value.spuImageList = imgList.value.map((o) => {
        return {
          imgName: o.name,
          imgUrl: (o.response && o.response.data) || o.url,
        }
      })
      spuParams.value.spuSaleAttrList = saleAttr.value

      const res: any = await reqAddOrUpdateSpu(spuParams.value)
      if (res.code === 200) {
        getElMessage(spuParams.value.id ? '修改属性值成功' : '添加属性值成功', 'success')
        cancel(!!spuParams.value.id)
      } else {
        getElMessage(spuParams.value.id ? '修改属性值失败' : '添加属性值失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    }
  }

  defineExpose({
    initalHasSpuData,
  })
</script>

<style lang="scss" scoped>
  .el-select {
    width: 20%;
  }
</style>
